package com.example.redislearning.service.impl;

import com.example.redislearning.entity.Course;
import com.example.redislearning.mapper.CourseMapper;
import com.example.redislearning.service.CourseService;
import com.example.redislearning.util.RedisKeyUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * 课程管理服务实现类
 * 集成Redis缓存、排行榜、搜索功能
 */
@Service
public class CourseServiceImpl implements CourseService {

    @Autowired
    private CourseMapper courseMapper;

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    private static final Integer COURSE_CACHE_EXPIRE = 30; // 30分钟
    private static final Integer COURSE_LIST_CACHE_EXPIRE = 15; // 15分钟
    private static final Integer HOT_COURSES_EXPIRE = 10; // 10分钟
    private static final Integer SEARCH_CACHE_EXPIRE = 5; // 5分钟

    /**
     * 创建新课程
     *
     * @param course 课程对象，包含课程基本信息
     * @return 创建成功的课程对象，包含生成的ID
     * @throws IllegalArgumentException 当课程标题为空时抛出异常
     */
    @Override
    @Transactional
    public Course createCourse(Course course) {
        if (course == null || course.getTitle() == null || course.getTitle().trim().isEmpty()) {
            throw new IllegalArgumentException("课程标题不能为空");
        }

        // 设置默认值
        course.setStatus(1);
        course.setViewCount(0);
        course.setSalesCount(0);
        course.setRating(0.0);
        course.setRatingCount(0);
        course.setCreatedAt(LocalDateTime.now());
        course.setUpdatedAt(LocalDateTime.now());

        // 保存到数据库
        courseMapper.insert(course);

        // 缓存新课程
        cacheCourseInfo(course);

        // 更新搜索索引
        updateSearchIndex(course);

        return course;
    }

    /**
     * 更新课程信息
     *
     * @param course 课程对象，包含需要更新的课程信息
     * @return 更新后的课程对象
     * @throws IllegalArgumentException 当课程信息不完整时抛出异常
     * @throws RuntimeException         当课程不存在时抛出异常
     */
    @Override
    @Transactional
    public Course updateCourse(Course course) {
        if (course == null || course.getId() == null) {
            throw new IllegalArgumentException("课程信息不完整");
        }

        // 检查课程是否存在
        Course existingCourse = getCourseById(course.getId());
        if (existingCourse == null) {
            throw new RuntimeException("课程不存在");
        }

        course.setUpdatedAt(LocalDateTime.now());

        // 更新数据库
        courseMapper.updateCourse(course);

        // 更新缓存
        cacheCourseInfo(course);

        // 更新搜索索引
        updateSearchIndex(course);

        // 清除相关列表缓存
        clearCourseListCaches();

        return course;
    }

    /**
     * 删除课程（软删除）
     *
     * @param courseId 课程ID
     * @return 删除成功返回true，失败返回false
     * @throws IllegalArgumentException 当课程ID为空时抛出异常
     */
    @Override
    @Transactional
    public boolean deleteCourse(Integer courseId) {
        if (courseId == null) {
            throw new IllegalArgumentException("课程ID不能为空");
        }

        // 软删除
        int result = courseMapper.deleteCourse(courseId);

        if (result > 0) {
            // 删除缓存
            String key = RedisKeyUtil.getCourseInfoKey(courseId);
            redisTemplate.delete(key);

            // 清除相关列表缓存
            clearCourseListCaches();

            // 从排行榜中移除
            removeFromLeaderboards(courseId);

            return true;
        }

        return false;
    }

    /**
     * 根据ID获取课程详情
     *
     * @param courseId 课程ID
     * @return 课程对象，不存在返回null
     * @throws IllegalArgumentException 当课程ID为空时抛出异常
     */
    @Override
    public Course getCourseById(Integer courseId) {
        if (courseId == null) {
            throw new IllegalArgumentException("课程ID不能为空");
        }

        // 先从缓存获取
        String key = RedisKeyUtil.getCourseInfoKey(courseId);
        Course course = (Course) redisTemplate.opsForValue().get(key);

        if (course == null) {
            // 缓存未命中，查询数据库
            course = courseMapper.selectById(courseId);
            if (course != null) {
                cacheCourseInfo(course);
            }
        }

        return course;
    }

    /**
     * 获取课程列表（分页）
     *
     * @param pageable 分页参数，包含页码和每页数量
     * @return 分页的课程列表
     * @throws IllegalArgumentException 当分页参数无效时抛出异常
     */
    @Override
    public Page<Course> getCourseList(Pageable pageable) {
        if (pageable == null) {
            throw new IllegalArgumentException("分页参数无效");
        }

        int page = pageable.getPageNumber();
        int size = pageable.getPageSize();
        String cacheKey = RedisKeyUtil.getCourseListKey(page + 1, size);
        List<Course> courses = (List<Course>) redisTemplate.opsForValue().get(cacheKey);

        if (courses == null) {
            // 缓存未命中，查询数据库
            int offset = page * size;
            courses = courseMapper.selectAllCourses(offset, size);

            if (courses != null && !courses.isEmpty()) {
                redisTemplate.opsForValue().set(cacheKey, courses, COURSE_LIST_CACHE_EXPIRE, TimeUnit.MINUTES);
            }
        }

        // 获取总数量用于分页
        Integer total = courseMapper.countAllCourses();

        return new PageImpl<>(courses != null ? courses : new ArrayList<>(), pageable, total);
    }

    /**
     * 搜索课程（支持关键词、分类、难度筛选）
     *
     * @param keyword    搜索关键词，可为空
     * @param category   课程分类，可为空
     * @param difficulty 课程难度，可为空
     * @param pageable   分页参数
     * @return 符合条件的分页课程列表
     * @throws IllegalArgumentException 当分页参数无效时抛出异常
     */
    @Override
    public Page<Course> searchCourses(String keyword, String category, String difficulty, Pageable pageable) {
        if (pageable == null) {
            throw new IllegalArgumentException("分页参数无效");
        }

        if (keyword == null || keyword.trim().isEmpty()) {
            return getCourseList(pageable);
        }

        int page = pageable.getPageNumber();
        int size = pageable.getPageSize();
        String cacheKey = RedisKeyUtil.getCourseSearchKey(keyword, category, page + 1, size);
        List<Course> courses = (List<Course>) redisTemplate.opsForValue().get(cacheKey);

        if (courses == null) {
            // 缓存未命中，查询数据库
            int offset = page * size;
            courses = courseMapper.searchCourses(keyword, category, offset, size);

            if (courses != null && !courses.isEmpty()) {
                redisTemplate.opsForValue().set(cacheKey, courses, SEARCH_CACHE_EXPIRE, TimeUnit.MINUTES);
            }
        }

        // 获取总数量用于分页
        Integer total = courseMapper.countSearchCourses(keyword, category);

        return new PageImpl<>(courses != null ? courses : new ArrayList<>(), pageable, total);
    }

    /**
     * 根据分类获取课程列表
     *
     * @param categoryId 分类ID
     * @param pageable   分页参数
     * @return 指定分类的分页课程列表
     * @throws IllegalArgumentException 当分页参数或分类ID无效时抛出异常
     */
    @Override
    public Page<Course> getCoursesByCategory(Integer categoryId, Pageable pageable) {
        if (pageable == null) {
            throw new IllegalArgumentException("分页参数无效");
        }

        if (categoryId == null) {
            throw new IllegalArgumentException("分类不能为空");
        }

        int page = pageable.getPageNumber();
        int size = pageable.getPageSize();
        String cacheKey = RedisKeyUtil.getCourseCategoryKey(categoryId, page + 1, size);
        List<Course> courses = (List<Course>) redisTemplate.opsForValue().get(cacheKey);

        if (courses == null) {
            // 缓存未命中，查询数据库
            int offset = page * size;
            courses = courseMapper.selectByCategory(categoryId, offset, size);

            if (courses != null && !courses.isEmpty()) {
                redisTemplate.opsForValue().set(cacheKey, courses, COURSE_LIST_CACHE_EXPIRE, TimeUnit.MINUTES);
            }
        }

        // 获取总数量用于分页
        Integer total = courseMapper.countCoursesByCategory(categoryId);

        return new PageImpl<>(courses != null ? courses : new ArrayList<>(), pageable, total);
    }

    /**
     * 增加课程浏览量
     *
     * @param courseId 课程ID
     * @return 更新成功返回true，失败返回false
     */
    @Override
    @Transactional
    public boolean incrementViews(Integer courseId) {
        if (courseId == null) {
            return false;
        }

        // 更新数据库
        int result = courseMapper.updateViewCount(courseId, 1);

        if (result > 0) {
            // 更新缓存
            Course course = getCourseById(courseId);
            if (course != null) {
                course.setViewCount(course.getViewCount() != null ? course.getViewCount() + 1 : 1);
                cacheCourseInfo(course);

                // 更新浏览量排行榜
                updateViewsLeaderboard(courseId, course.getViewCount());
            }

            // 清除列表缓存
            clearCourseListCaches();

            return true;
        }

        return false;
    }

    /**
     * 增加课程销量
     *
     * @param courseId 课程ID
     * @param quantity 增加的销量数量
     * @return 更新成功返回true，失败返回false
     * @throws IllegalArgumentException 当参数无效时抛出异常
     */
    @Override
    @Transactional
    public boolean incrementSales(Integer courseId, Integer quantity) {
        if (courseId == null || quantity == null || quantity <= 0) {
            throw new IllegalArgumentException("参数无效");
        }
        Course byId = courseMapper.selectById(courseId);
        // TODO 需要检查
        quantity += byId.getSalesCount();

        // 更新数据库
        int result = courseMapper.updateSalesCount(courseId, quantity);

        if (result > 0) {
            // 更新缓存
            Course course = getCourseById(courseId);
            if (course != null) {
                course.setSalesCount(course.getSalesCount() != null ? course.getSalesCount() + quantity : quantity);
                cacheCourseInfo(course);

                // 更新销量排行榜
                updateSalesLeaderboard(courseId, course.getSalesCount());
            }

            // 清除列表缓存
            clearCourseListCaches();

            return true;
        }

        return false;
    }


    /**
     * 更新课程评分
     *
     * @param courseId    课程ID
     * @param newRating   新评分（0-5分）
     * @param ratingCount 评分人数
     * @return 更新成功返回true，失败返回false
     * @throws IllegalArgumentException 当评分参数无效时抛出异常
     */
    @Override
    @Transactional
    public boolean updateRating(Integer courseId, Double newRating, Integer ratingCount) {
        if (courseId == null || newRating == null || newRating < 0 || newRating > 5) {
            throw new IllegalArgumentException("评分参数无效");
        }

        // 更新数据库
        int result = courseMapper.updateRating(courseId, newRating, ratingCount);

        if (result > 0) {
            // 更新缓存
            Course course = getCourseById(courseId);
            if (course != null) {
                course.setRating(newRating);
                course.setRatingCount(ratingCount);
                cacheCourseInfo(course);

                // 更新评分排行榜
                updateRatingLeaderboard(courseId, newRating);
            }

            return true;
        }

        return false;
    }

    /**
     * 获取热门课程列表
     *
     * @param limit 限制数量
     * @return 热门课程列表，按销量和评分排序
     * @throws IllegalArgumentException 当限制数量小于等于0时抛出异常
     */
    @Override
    public List<Course> getHotCourses(int limit) {
        if (limit <= 0) {
            throw new IllegalArgumentException("限制数量必须大于0");
        }

        String cacheKey = RedisKeyUtil.getHotCoursesKey(limit);
        List<Course> courses = (List<Course>) redisTemplate.opsForValue().get(cacheKey);

        if (courses == null) {
            // 缓存未命中，从数据库获取
            courses = courseMapper.getHotCourses(limit);

            if (courses != null && !courses.isEmpty()) {
                // 获取课程详细信息
                List<Course> detailedCourses = new ArrayList<>();
                for (Course course : courses) {
                    Course detailed = getCourseById(course.getId());
                    if (detailed != null) {
                        detailedCourses.add(detailed);
                    }
                }

                courses = detailedCourses;
                redisTemplate.opsForValue().set(cacheKey, courses, HOT_COURSES_EXPIRE, TimeUnit.MINUTES);
            }
        }

        return courses != null ? courses : new ArrayList<>();
    }

    /**
     * 获取评分最高的课程列表
     *
     * @param limit 限制数量
     * @return 评分最高的课程列表，按评分降序排列
     * @throws IllegalArgumentException 当限制数量小于等于0时抛出异常
     */
    @Override
    public List<Course> getTopRatedCourses(int limit) {
        if (limit <= 0) {
            throw new IllegalArgumentException("限制数量必须大于0");
        }

        String cacheKey = RedisKeyUtil.getTopRatedCoursesKey(limit);
        List<Course> courses = (List<Course>) redisTemplate.opsForValue().get(cacheKey);

        if (courses == null) {
            // 从Redis排行榜获取
            Set<String> courseIds = stringRedisTemplate.opsForZSet().reverseRange(
                    RedisKeyUtil.getRatingLeaderboardKey(), 0, limit - 1);

            if (courseIds != null && !courseIds.isEmpty()) {
                courses = new ArrayList<>();
                for (String courseIdStr : courseIds) {
                    Integer courseId = Integer.parseInt(courseIdStr);
                    Course course = getCourseById(courseId);
                    if (course != null) {
                        courses.add(course);
                    }
                }
            } else {
                // Redis未命中，从数据库获取
                courses = courseMapper.getTopRatedCourses(limit);

                // 同步到Redis
                for (Course course : courses) {
                    stringRedisTemplate.opsForZSet().add(
                            RedisKeyUtil.getRatingLeaderboardKey(),
                            String.valueOf(course.getId()),
                            course.getRating());
                }
            }

            if (courses != null && !courses.isEmpty()) {
                redisTemplate.opsForValue().set(cacheKey, courses, HOT_COURSES_EXPIRE, TimeUnit.MINUTES);
            }
        }

        return courses != null ? courses : new ArrayList<>();
    }

    /**
     * 获取销量最高的课程列表
     *
     * @param limit 限制数量
     * @return 销量最高的课程列表，按销量降序排列
     * @throws IllegalArgumentException 当限制数量小于等于0时抛出异常
     */
    @Override
    public List<Course> getTopSellingCourses(int limit) {
        if (limit <= 0) {
            throw new IllegalArgumentException("限制数量必须大于0");
        }

        String cacheKey = RedisKeyUtil.getTopSellingCoursesKey(limit);
        List<Course> courses = (List<Course>) redisTemplate.opsForValue().get(cacheKey);

        if (courses == null) {
            // 从Redis排行榜获取
            Set<String> courseIds = stringRedisTemplate.opsForZSet().reverseRange(
                    RedisKeyUtil.getSalesLeaderboardKey(), 0, limit - 1);

            if (courseIds != null && !courseIds.isEmpty()) {
                courses = new ArrayList<>();
                for (String courseIdStr : courseIds) {
                    Integer courseId = Integer.parseInt(courseIdStr);
                    Course course = getCourseById(courseId);
                    if (course != null) {
                        courses.add(course);
                    }
                }
            } else {
                // Redis未命中，从数据库获取
                courses = courseMapper.getTopSellingCourses(limit);

                // 同步到Redis
                for (Course course : courses) {
                    stringRedisTemplate.opsForZSet().add(
                            RedisKeyUtil.getSalesLeaderboardKey(),
                            String.valueOf(course.getId()),
                            course.getSalesCount() != null ? course.getSalesCount().doubleValue() : 0.0);
                }
            }

            if (courses != null && !courses.isEmpty()) {
                redisTemplate.opsForValue().set(cacheKey, courses, HOT_COURSES_EXPIRE, TimeUnit.MINUTES);
            }
        }

        return courses != null ? courses : new ArrayList<>();
    }

    /**
     * 获取浏览量最高的课程列表
     *
     * @param limit 限制数量
     * @return 浏览量最高的课程列表，按浏览量降序排列
     * @throws IllegalArgumentException 当限制数量小于等于0时抛出异常
     */
    @Override
    public List<Course> getMostViewedCourses(int limit) {
        if (limit <= 0) {
            throw new IllegalArgumentException("限制数量必须大于0");
        }

        String cacheKey = RedisKeyUtil.getMostViewedCoursesKey(limit);
        List<Course> courses = (List<Course>) redisTemplate.opsForValue().get(cacheKey);

        if (courses == null) {
            // 从Redis排行榜获取
            Set<String> courseIds = stringRedisTemplate.opsForZSet().reverseRange(
                    RedisKeyUtil.getViewsLeaderboardKey(), 0, limit - 1);

            if (courseIds != null && !courseIds.isEmpty()) {
                courses = new ArrayList<>();
                for (String courseIdStr : courseIds) {
                    Integer courseId = Integer.parseInt(courseIdStr);
                    Course course = getCourseById(courseId);
                    if (course != null) {
                        courses.add(course);
                    }
                }
            } else {
                // Redis未命中，从数据库获取
                courses = courseMapper.getMostViewedCourses(limit);

                // 同步到Redis
                for (Course course : courses) {
                    stringRedisTemplate.opsForZSet().add(
                            RedisKeyUtil.getViewsLeaderboardKey(),
                            String.valueOf(course.getId()),
                            course.getViewCount() != null ? course.getViewCount().doubleValue() : 0.0);
                }
            }

            if (courses != null && !courses.isEmpty()) {
                redisTemplate.opsForValue().set(cacheKey, courses, HOT_COURSES_EXPIRE, TimeUnit.MINUTES);
            }
        }

        return courses != null ? courses : new ArrayList<>();
    }


    /**
     * 更新课程评分（计算平均评分）
     *
     * @param courseId  课程ID
     * @param newRating 新评分（0-5分）
     * @return 更新后的平均评分
     * @throws IllegalArgumentException 当评分参数无效时抛出异常
     * @throws RuntimeException         当课程不存在时抛出异常
     */
    @Override
    @Transactional
    public Double updateCourseRating(Integer courseId, Double newRating) {
        if (courseId == null || newRating == null || newRating < 0 || newRating > 5) {
            throw new IllegalArgumentException("评分参数无效");
        }

        Course course = getCourseById(courseId);
        if (course == null) {
            throw new RuntimeException("课程不存在");
        }

        // 更新评分和评分人数
        Integer currentRatingCount = course.getRatingCount() != null ? course.getRatingCount() : 0;
        Double currentRating = course.getRating() != null ? course.getRating() : 0.0;

        // 计算新的平均评分（简化处理，实际应该记录每个用户的评分）
        Double updatedRating = (currentRating * currentRatingCount + newRating) / (currentRatingCount + 1);

        course.setRating(updatedRating);
        course.setRatingCount(currentRatingCount + 1);
        course.setUpdatedAt(LocalDateTime.now());

        // 更新数据库
        courseMapper.updateCourse(course);

        // 更新缓存
        cacheCourseInfo(course);

        // 更新评分排行榜
        updateRatingLeaderboard(courseId, updatedRating);

        return updatedRating;
    }

    /**
     * 增加课程销量
     *
     * @param courseId  课程ID
     * @param increment 增加的销量数量
     * @return 更新后的总销量
     * @throws IllegalArgumentException 当参数无效时抛出异常
     * @throws RuntimeException         当课程不存在时抛出异常
     */
    @Override
    @Transactional
    public Integer incrementCourseSales(Integer courseId, Integer increment) {
        if (courseId == null || increment == null || increment <= 0) {
            throw new IllegalArgumentException("参数无效");
        }

        Course course = getCourseById(courseId);
        if (course == null) {
            throw new RuntimeException("课程不存在");
        }

        Integer currentSales = course.getSalesCount() != null ? course.getSalesCount() : 0;
        Integer newSales = currentSales + increment;

        course.setSalesCount(newSales);
        course.setUpdatedAt(LocalDateTime.now());

        // 更新数据库
        courseMapper.updateCourse(course);

        // 更新缓存
        cacheCourseInfo(course);

        // 更新销量排行榜
        updateSalesLeaderboard(courseId, newSales);

        return newSales;
    }

    /**
     * 获取课程销量
     *
     * @param courseId 课程ID
     * @return 课程销量，课程不存在返回0
     * @throws IllegalArgumentException 当课程ID为空时抛出异常
     */
    @Override
    public Integer getCourseSales(Integer courseId) {
        if (courseId == null) {
            throw new IllegalArgumentException("课程ID不能为空");
        }

        Course course = getCourseById(courseId);
        return course != null ? (course.getSalesCount() != null ? course.getSalesCount() : 0) : 0;
    }

    /**
     * 获取热门课程排行榜（包含排名信息）
     *
     * @param limit 限制数量
     * @return 热门课程列表，每个元素包含排名、课程信息、销量等数据的Map
     * @throws IllegalArgumentException 当限制数量小于等于0时抛出异常
     */
    @Override
    public List<Map<String, Object>> getPopularCourses(int limit) {
        if (limit <= 0) {
            throw new IllegalArgumentException("限制数量必须大于0");
        }

        List<Course> topSelling = getTopSellingCourses(limit);
        List<Map<String, Object>> popularCourses = new ArrayList<>();

        for (int i = 0; i < topSelling.size() && i < limit; i++) {
            Course course = topSelling.get(i);
            Map<String, Object> courseMap = new HashMap<>();
            courseMap.put("rank", i + 1);
            courseMap.put("course", course);
            courseMap.put("sales", course.getSalesCount());
            popularCourses.add(courseMap);
        }

        return popularCourses;
    }

    /**
     * 获取推荐课程列表（简化实现：返回评分最高的课程）
     *
     * @param userId 用户ID（当前未使用，预留参数）
     * @param limit  限制数量
     * @return 推荐课程列表
     * @throws IllegalArgumentException 当限制数量小于等于0时抛出异常
     */
    @Override
    public List<Course> getRecommendedCourses(Integer userId, int limit) {
        if (limit <= 0) {
            throw new IllegalArgumentException("限制数量必须大于0");
        }

        // 简化推荐算法：返回评分最高的课程
        return getTopRatedCourses(limit);
    }

    /**
     * 检查课程是否存在
     *
     * @param courseId 课程ID
     * @return 存在返回true，不存在返回false
     */
    @Override
    public boolean isCourseExists(Integer courseId) {
        if (courseId == null) {
            return false;
        }

        String key = RedisKeyUtil.getCourseInfoKey(courseId);
        Course course = (Course) redisTemplate.opsForValue().get(key);

        if (course != null) {
            return true;
        }

        // 缓存未命中，查询数据库
        course = courseMapper.selectById(courseId);
        if (course != null) {
            cacheCourseInfo(course);
            return true;
        }

        return false;
    }

    /**
     * 根据ID列表批量获取课程
     *
     * @param courseIds 课程ID列表
     * @return 课程列表，不存在的课程将被忽略
     */
    @Override
    public List<Course> getCoursesByIds(List<Integer> courseIds) {
        if (courseIds == null || courseIds.isEmpty()) {
            return new ArrayList<>();
        }

        List<Course> courses = new ArrayList<>();
        List<Integer> missingIds = new ArrayList<>();

        // 先从缓存获取
        for (Integer courseId : courseIds) {
            String key = RedisKeyUtil.getCourseInfoKey(courseId);
            Course course = (Course) redisTemplate.opsForValue().get(key);
            if (course != null) {
                courses.add(course);
            } else {
                missingIds.add(courseId);
            }
        }

        // 缓存未命中的，批量查询数据库
        if (!missingIds.isEmpty()) {
            List<Course> dbCourses = courseMapper.selectByIds(missingIds);
            for (Course course : dbCourses) {
                if (course != null) {
                    cacheCourseInfo(course);
                    courses.add(course);
                }
            }
        }

        return courses;
    }

    /**
     * 获取课程统计信息（包含浏览量、销量、评分、排名等）
     *
     * @param courseId 课程ID
     * @return 包含课程统计信息的Map，包含浏览量、销量、评分、排名等数据
     * @throws IllegalArgumentException 当课程ID为空时抛出异常
     * @throws RuntimeException         当课程不存在时抛出异常
     */
    @Override
    public Map<String, Object> getCourseStatistics(Integer courseId) {
        if (courseId == null) {
            throw new IllegalArgumentException("课程ID不能为空");
        }

        Course course = getCourseById(courseId);
        if (course == null) {
            throw new RuntimeException("课程不存在");
        }

        Map<String, Object> stats = new HashMap<>();
        stats.put("courseId", course.getId());
        stats.put("title", course.getTitle());
        stats.put("category", course.getCategoryId());
        stats.put("views", course.getViewCount() != null ? course.getViewCount() : 0L);
        stats.put("sales", course.getSalesCount() != null ? course.getSalesCount() : 0L);
        stats.put("rating", course.getRating() != null ? course.getRating() : 0.0);
        stats.put("ratingCount", course.getRatingCount() != null ? course.getRatingCount() : 0L);
        stats.put("createTime", course.getCreatedAt());

        // 获取排名信息
        Long viewsRank = stringRedisTemplate.opsForZSet().reverseRank(
                RedisKeyUtil.getViewsLeaderboardKey(), String.valueOf(courseId));
        Long salesRank = stringRedisTemplate.opsForZSet().reverseRank(
                RedisKeyUtil.getSalesLeaderboardKey(), String.valueOf(courseId));
        Long ratingRank = stringRedisTemplate.opsForZSet().reverseRank(
                RedisKeyUtil.getRatingLeaderboardKey(), String.valueOf(courseId));

        stats.put("viewsRank", viewsRank != null ? viewsRank + 1 : null);
        stats.put("salesRank", salesRank != null ? salesRank + 1 : null);
        stats.put("ratingRank", ratingRank != null ? ratingRank + 1 : null);

        return stats;
    }

    // 私有辅助方法

    /**
     * 缓存课程信息到Redis
     *
     * @param course 课程对象
     */
    private void cacheCourseInfo(Course course) {
        if (course != null && course.getId() != null) {
            String key = RedisKeyUtil.getCourseInfoKey(course.getId());
            redisTemplate.opsForValue().set(key, course, COURSE_CACHE_EXPIRE, TimeUnit.MINUTES);
        }
    }

    /**
     * 更新课程搜索索引
     *
     * @param course 课程对象
     */
    private void updateSearchIndex(Course course) {
        // 这里可以实现更复杂的搜索索引
        // 简化处理：将关键词存储在Redis中用于快速搜索
        if (course != null && course.getTitle() != null) {
            String searchKey = RedisKeyUtil.getCourseSearchIndexKey();
            stringRedisTemplate.opsForSet().add(searchKey, course.getTitle().toLowerCase());
        }
    }

    /**
     * 清除所有课程列表相关的缓存
     * 实际项目中可以使用Redis的key模式匹配或设置缓存标签
     */
    private void clearCourseListCaches() {
        // 清除所有课程列表相关的缓存
        // 实际项目中可以使用Redis的key模式匹配或设置缓存标签
        Set<String> keys = stringRedisTemplate.keys("course:list:*");
        if (keys != null) {
            stringRedisTemplate.delete(keys);
        }
    }

    /**
     * 从所有排行榜中移除指定课程
     *
     * @param courseId 课程ID
     */
    private void removeFromLeaderboards(Integer courseId) {
        String courseIdStr = String.valueOf(courseId);
        stringRedisTemplate.opsForZSet().remove(RedisKeyUtil.getViewsLeaderboardKey(), courseIdStr);
        stringRedisTemplate.opsForZSet().remove(RedisKeyUtil.getSalesLeaderboardKey(), courseIdStr);
        stringRedisTemplate.opsForZSet().remove(RedisKeyUtil.getRatingLeaderboardKey(), courseIdStr);
    }

    /**
     * 更新课程浏览量排行榜
     *
     * @param courseId 课程ID
     * @param views    浏览量
     */
    private void updateViewsLeaderboard(Integer courseId, Integer views) {
        String key = RedisKeyUtil.getViewsLeaderboardKey();
        stringRedisTemplate.opsForZSet().add(key, String.valueOf(courseId), views);
        stringRedisTemplate.expire(key, HOT_COURSES_EXPIRE, TimeUnit.MINUTES);
    }

    private void updateRatingLeaderboard(Integer courseId, Double updatedRating) {
        String key = RedisKeyUtil.getRatingLeaderboardKey();
        stringRedisTemplate.opsForZSet().add(key, String.valueOf(courseId), updatedRating);
        stringRedisTemplate.expire(key, HOT_COURSES_EXPIRE, TimeUnit.MINUTES);
    }


    /**
     * 更新课程销量排行榜
     *
     * @param courseId 课程ID
     * @param sales    销量
     */
    private void updateSalesLeaderboard(Integer courseId, Integer sales) {
        String key = RedisKeyUtil.getSalesLeaderboardKey();
        stringRedisTemplate.opsForZSet().add(key, String.valueOf(courseId), sales);
        stringRedisTemplate.expire(key, HOT_COURSES_EXPIRE, TimeUnit.MINUTES);
    }


    /**
     * 获取最新课程
     *
     * @param limit 限制返回的课程数量
     * @return 最新课程列表
     */
    @Override
    public List<Course> getLatestCourses(int limit) {
        // 先从缓存获取
        String cacheKey = RedisKeyUtil.getLatestCoursesKey(limit);
        List<Course> courses = (List<Course>) redisTemplate.opsForValue().get(cacheKey);

        if (courses == null) {
            // 缓存未命中，查询数据库
            courses = courseMapper.selectLatestCourses(limit);

            if (courses != null && !courses.isEmpty()) {
                redisTemplate.opsForValue().set(cacheKey, courses, COURSE_LIST_CACHE_EXPIRE, TimeUnit.MINUTES);
            }
        }

        return courses;
    }

    /**
     * 获取免费课程
     *
     * @param page 页码
     * @param size 每页数量
     * @return 免费课程列表
     */
    @Override
    public List<Course> getFreeCourses(int page, int size) {
        int offset = page * size;

        // 先从缓存获取
        String cacheKey = RedisKeyUtil.getFreeCoursesKey(page, size);
        List<Course> courses = (List<Course>) redisTemplate.opsForValue().get(cacheKey);

        if (courses == null) {
            // 缓存未命中，查询数据库
            courses = courseMapper.selectFreeCourses(size);

            if (courses != null && !courses.isEmpty()) {
                redisTemplate.opsForValue().set(cacheKey, courses, COURSE_LIST_CACHE_EXPIRE, TimeUnit.MINUTES);
            }
        }

        return courses;
    }

    /**
     * 根据价格区间获取课程
     *
     * @param minPrice 最低价格
     * @param maxPrice 最高价格
     * @param page     页码
     * @param size     每页数量
     * @return 价格区间内的课程列表
     */
    @Override
    public List<Course> getCoursesByPriceRange(Double minPrice, Double maxPrice, int page, int size) {
        int offset = page * size;

        // 先从缓存获取
        String cacheKey = RedisKeyUtil.getPriceRangeCoursesKey(minPrice, maxPrice, page, size);
        List<Course> courses = (List<Course>) redisTemplate.opsForValue().get(cacheKey);

        if (courses == null) {
            // 缓存未命中，查询数据库
            courses = courseMapper.selectByPriceRange(minPrice, maxPrice, offset, size);

            if (courses != null && !courses.isEmpty()) {
                redisTemplate.opsForValue().set(cacheKey, courses, COURSE_LIST_CACHE_EXPIRE, TimeUnit.MINUTES);
            }
        }

        return courses;
    }
}
